home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / DCC_3DE.ZIP / 3DSC.PAS < prev    next >
Pascal/Delphi Source File  |  1996-01-25  |  10KB  |  340 lines

  1. { Can handle only up to 16384 faces objects
  2.  (C) X-wizard/DCC VR LABS
  3.  The chevy is converted by EMS version of this converter,   }
  4.  
  5. {usage: 3DSC object.3ds object.dcc SCALE (smaller->bigger object}
  6. {example: 3DSC object.3ds object.dcc 50}
  7.  
  8. uses crt;
  9. type vertex=record
  10.           x:integer;
  11.           y:integer;
  12.           z:integer;
  13.           end;
  14.      cords=record
  15.           x:integer;
  16.           y:integer;
  17.           z:integer;
  18.           xy :integer;
  19.           end;
  20.      face=record
  21.           a:integer;
  22.           b:integer;
  23.           c:integer;
  24.           n:vertex;
  25.           vn:array[1..3] of vertex;
  26.           fxy :integer;
  27.           end;
  28.      vlist=array[0..($fffe div 4)-1] of ^cords;
  29.      flist=array[0..($fffe div 4)-1] of ^face;
  30.      object3d=record
  31.             faces:word;
  32.             vertices:word;
  33.             face:^flist;
  34.             vert:^vlist;
  35.             end;
  36.  
  37. var obj:array[1..1000] of ^object3d;
  38. procedure calcnormals(var list:flist;var vl:vlist;fcount:word);
  39. var f,f1:word;
  40.     a,b,c:word;
  41.     fc:array[1..3] of word;
  42.     a1,b1,c1:word;
  43.     x,y,z:array[1..3] of real;
  44.     tv:array[1..3] of vertex;
  45.     i,j,k,d:real;
  46. begin;
  47. {surface normals}
  48. clrscr;
  49. for F:=0 to fcount-1 do
  50. begin;
  51. gotoxy(1,1);
  52. writelN('Calculating surface normals for face: ',f:5);
  53. a:=list[f]^.a;
  54. b:=list[f]^.b;
  55. c:=list[f]^.c;
  56. x[1]:=vl[a]^.x / 256;
  57. y[1]:=vl[a]^.y / 256;
  58. z[1]:=vl[a]^.z / 256;
  59. x[2]:=vl[b]^.x / 256;
  60. y[2]:=vl[b]^.y / 256;
  61. z[2]:=vl[b]^.z / 256;
  62. x[3]:=vl[c]^.x / 256;
  63. y[3]:=vl[c]^.y / 256;
  64. z[3]:=vl[c]^.z / 256;
  65. i:=(((Y[2] - y[1]) * (Z[3] - Z[1])) - ((Z[2] - Z[1]) * (Y[3] - Y[1])));
  66. j:=(((Z[2] - Z[1]) * (X[3] - X[1])) - ((X[2] - X[1]) * (Z[3] - Z[1])));
  67. k:=(((X[2] - X[1]) * (Y[3] - Y[1])) - ((Y[2] - Y[1]) * (X[3] - X[1])));
  68. d:= sqrt(((i * i) + (j * j)+ (k * k)));
  69. if d=0 then d:=1;
  70. i:= (i / d);
  71. j:= (j / d);
  72. k:= (k / d);
  73. list[f]^.n.x:=round(i* 256);
  74. list[f]^.n.y:=round(j* 256);
  75. list[f]^.n.z:=round(k* 256);
  76. end;
  77. {vertex normals}
  78. for F:=0 to fcount-1 do
  79. begin;
  80. fc[1]:=0;
  81. fc[2]:=0;
  82. fc[3]:=0;
  83. a:=list[f]^.a;
  84. b:=list[f]^.b;
  85. c:=list[f]^.c;
  86. tv[1].x:=0;
  87. tv[1].y:=0;
  88. tv[1].z:=0;
  89. tv[2].x:=0;
  90. tv[2].y:=0;
  91. tv[2].z:=0;
  92. tv[3].x:=0;
  93. tv[3].y:=0;
  94. tv[3].z:=0;
  95. for F1:=0 to fcount-1 do
  96. begin;
  97. a1:=list[f1]^.a;
  98. b1:=list[f1]^.b;
  99. c1:=list[f1]^.c;
  100. if (a=a1)or(a=b1)or(a=c1) then begin;
  101.                                tv[1].x:=tv[1].x+list[f1]^.n.x;
  102.                                tv[1].y:=tv[1].y+list[f1]^.n.y;
  103.                                tv[1].z:=tv[1].z+list[f1]^.n.z;
  104.                                fc[1]:=fc[1]+1;
  105.                                end;
  106. if (b=a1)or(b=b1)or(b=c1) then begin;
  107.                                tv[2].x:=tv[2].x+list[f1]^.n.x;
  108.                                tv[2].y:=tv[2].y+list[f1]^.n.y;
  109.                                tv[2].z:=tv[2].z+list[f1]^.n.z;
  110.                                fc[2]:=fc[2]+1;
  111.                                end;
  112. if (c=a1)or(c=b1)or(c=c1) then begin;
  113.                                tv[3].x:=tv[3].x+list[f1]^.n.x;
  114.                                tv[3].y:=tv[3].y+list[f1]^.n.y;
  115.                                tv[3].z:=tv[3].z+list[f1]^.n.z;
  116.                                fc[3]:=fc[3]+1;
  117.                                end;
  118. end;
  119.  
  120. tv[1].x:=tv[1].x div fc[1];
  121. tv[1].y:=tv[1].y div fc[1];
  122. tv[1].z:=tv[1].z div fc[1];
  123. list[f]^.vn[1].x:=tv[1].x;
  124. list[f]^.vn[1].y:=tv[1].y;
  125. list[f]^.vn[1].z:=tv[1].z;
  126. tv[2].x:=tv[2].x div fc[2];
  127. tv[2].y:=tv[2].y div fc[2];
  128. tv[2].z:=tv[2].z div fc[2];
  129. list[f]^.vn[2].x:=tv[2].x;
  130. list[f]^.vn[2].y:=tv[2].y;
  131. list[f]^.vn[2].z:=tv[2].z;
  132. tv[3].x:=tv[3].x div fc[3];
  133. tv[3].y:=tv[3].y div fc[3];
  134. tv[3].z:=tv[3].z div fc[3];
  135. list[f]^.vn[3].x:=tv[3].x;
  136. list[f]^.vn[3].y:=tv[3].y;
  137. list[f]^.vn[3].z:=tv[3].z;
  138. list[f]^.fxy:=0;
  139. gotoxy(1,1);
  140. writelN('Calculated vertex normals for face:   ',f:5);
  141. writelN('Vertex normal a.x:',tv[1].x:10);
  142. writelN('Vertex normal a.y:',tv[1].y:10);
  143. writelN('Vertex normal a.z:',tv[1].z:10);
  144. writelN('Vertex normal b.x:',tv[2].x:10);
  145. writelN('Vertex normal b.y:',tv[2].y:10);
  146. writelN('Vertex normal b.z:',tv[2].z:10);
  147. writelN('Vertex normal c.x:',tv[3].x:10);
  148. writelN('Vertex normal c.y:',tv[3].y:10);
  149. writelN('Vertex normal c.z:',tv[3].z:10);
  150. end;
  151. end;
  152. procedure center(vcount:WORD;var list:vlist);
  153. var vert:word;
  154.     cp,mx,mi:vertex;
  155. begin;
  156. mx.x:=list[0]^.x;
  157. mx.y:=list[0]^.y;
  158. mx.z:=list[0]^.z;
  159. mi.x:=list[0]^.x;
  160. mi.y:=list[0]^.y;
  161. mi.z:=list[0]^.z;
  162. for vert:=0 to vcount-1 do
  163. begin;
  164. if list[vert]^.x>mx.x then mx.x:=list[vert]^.x;
  165. if list[vert]^.y>mx.y then mx.y:=list[vert]^.y;
  166. if list[vert]^.z>mx.z then mx.z:=list[vert]^.z;
  167. if list[vert]^.x<mi.x then mi.x:=list[vert]^.x;
  168. if list[vert]^.y<mi.y then mi.y:=list[vert]^.y;
  169. if list[vert]^.z<mi.z then mi.z:=list[vert]^.z;
  170. end;
  171. cp.x:=(mi.x+mx.x)div 2;
  172. cp.y:=(mi.y+mx.y)div 2;
  173. cp.z:=(mi.z+mx.z)div 2;
  174. for vert:=0 to vcount-1 do
  175. begin;
  176. list[vert]^.x:=list[vert]^.x-cp.x;
  177. list[vert]^.y:=list[vert]^.y-cp.y;
  178. list[vert]^.z:=list[vert]^.z-cp.z;
  179. list[vert]^.xy:=round((list[vert]^.x * list[vert]^.y)/256);
  180.                 {DONT USE XY COZ PASCAL SUCKS!!!!!!!!!!!LIKE HELLL}
  181. end;
  182. end;
  183. procedure saveDCC(fname:string;start,eend:word);
  184. var f:file;
  185.     nmb,d:word;
  186. begin;
  187. assign(f,fname);
  188. rewrite(f,1);
  189. for nmb:=start to eend do
  190. begin;
  191. blockwrite(f,obj[nmb]^.faces,sizeof(obj[nmb]^.faces));
  192. blockwrite(f,obj[nmb]^.vertices,sizeof(obj[nmb]^.vertices));
  193. for d:=0 to obj[nmb]^.faces-1 do
  194. begin;
  195. blockwrite(f,obj[nmb]^.face^[d]^,sizeof(obj[nmb]^.face^[d]^));
  196. end;
  197. for d:=0 to obj[nmb]^.vertices-1 do
  198. begin;
  199. blockwrite(f,obj[nmb]^.vert^[d]^,sizeof(obj[nmb]^.vert^[d]^));
  200. end;
  201. end;
  202. close(f);
  203. end;
  204.  
  205. procedure readword(var f:file;var str:string);
  206. var ch:byte;
  207. begin;
  208. str:='';
  209. repeat;
  210. blockread(f,ch,1);
  211. if ch<>0 then str:=str+chr(ch);
  212. until ch=0;
  213. end;
  214.  
  215. var f:file;
  216.     objcnt:word;
  217.     chunkid:word;
  218.     filesize,nextchunk:longint;
  219.     name:string;
  220.     skip:boolean;
  221.     xtra,a,b,c,v,faces,vertices:word;
  222.     scale:real;
  223.     e:integer;
  224.     rx,ry,rz:single;
  225. begin;
  226. {scale:=30;}
  227. val(paramstr(3),scale,e);
  228. if e<>0 then begin;
  229.              writeln('error');
  230.              end;
  231. assign(f,paramstr(1){'..\dcc.3ds'});
  232. reset(f,1);
  233. blockreaD(f,chunkid,2);
  234. blockreaD(f,filesize,4);
  235. if chunkid<>$4d4d then begin;
  236.                        writeln('not a 3DS file....');
  237.                        close(f);
  238.                        halt;
  239.                        end;
  240. objcnt:=0;
  241. repeat
  242. blockreaD(f,chunkid,2);
  243. blockreaD(f,nextchunk,4);
  244. skip:=true;
  245. if chunkid=$3d3d then begin;
  246.                       blockreaD(f,chunkid,2);
  247.                       blockreaD(f,nextchunk,4);
  248.                       skip:=true;
  249.                       end;
  250. if chunkid=$4000 then begin;
  251.                       readword(f,name);
  252.                       writeln('Obj name:',name);
  253.                       objcnt:=objcnt+1;
  254.                       new(obj[objcnt]);
  255.                       skip:=false;
  256.                       end;
  257. if chunkid=$4600 then begin;
  258.                       writeln('A light skipped....');
  259.                       dispose(obj[objcnt]);
  260.                       objcnt:=objcnt-1;
  261.                       end;
  262. if chunkid=$4700 then begin;
  263.                       writeln('A camera skipped....');
  264.                       dispose(obj[objcnt]);
  265.                       objcnt:=objcnt-1;
  266.                       end;
  267. if chunkid=$4100 then begin;
  268.                       writeln('A true object loading mesh...');
  269.                       skip:=false;
  270.                       end;
  271. if chunkid=$4110 then begin;
  272.                       {vertex list}
  273.                       blockread(f,vertices,2);
  274.                       obj[objcnt]^.vertices:=vertices;
  275.                       getmem(obj[objcnt]^.vert,vertices*4{sizeof(cords)});
  276.                       clrscr;
  277.                       for v:=0 to vertices-1 do
  278.                       begin;
  279.                       new(obj[objcnt]^.vert^[v]);
  280.                       blockread(f,rx,4);
  281.                       blockread(f,ry,4);
  282.                       blockread(f,rz,4);
  283.                       {X:0.253727     Y:-0.000012     Z:-20.659882}
  284.                       rx:=rx/scale;
  285.                       ry:=ry/scale;
  286.                       rz:=rz/scale;
  287.                       obj[objcnt]^.vert^[v]^.x:=round(rx*256);
  288.                       obj[objcnt]^.vert^[v]^.y:=round(ry*256);
  289.                       obj[objcnt]^.vert^[v]^.z:=round(rz*256);
  290.                       gotoxy(1,1);
  291.                       writeln('vertices:',vertices);
  292.                       writeln('vertex x:',obj[objcnt]^.vert^[v]^.x);
  293.                       writeln('vertex y:',obj[objcnt]^.vert^[v]^.y);
  294.                       writeln('vertex z:',obj[objcnt]^.vert^[v]^.z);
  295.                       end;
  296.                       skip:=false;
  297.                       end;
  298. if chunkid=$4120 then begin;
  299.                       {face list}
  300.                       blockread(f,faces,2);
  301.                       obj[objcnt]^.faces:=faces;
  302.                       getmem(obj[objcnt]^.face,faces*4{sizeof(face)});
  303.                       clrscr;
  304.                       for v:=0 to faces-1 do
  305.                       begin;
  306.                       new(obj[objcnt]^.face^[v]);
  307.                       blockread(f,c,2);
  308.                       blockread(f,b,2);
  309.                       blockread(f,a,2);
  310.                       blockread(f,xtra,2);
  311.  
  312.                       obj[objcnt]^.face^[v]^.a:=a;
  313.                       obj[objcnt]^.face^[v]^.b:=b;
  314.                       obj[objcnt]^.face^[v]^.c:=c;
  315.                       gotoxy(1,1);
  316.                       writeln('faces:',faces:8);
  317.                       writeln('face a:',obj[objcnt]^.face^[v]^.a:8);
  318.                       writeln('face b:',obj[objcnt]^.face^[v]^.b:8);
  319.                       writeln('face c:',obj[objcnt]^.face^[v]^.c:8);
  320.                       end;
  321.                       skip:=false;
  322.                       end;
  323. if skip then begin;
  324.              seek(f,filepos(f)+nextchunk-6);
  325.              end;
  326. until eof(f);
  327. close(f);
  328. if objcnt=0 then begin;
  329.                  writeln('No objects ....');
  330.                  halt;
  331.                  end;
  332. for v:=1 to objcnt do
  333. begin;
  334. center(obj[v]^.vertices,obj[v]^.vert^);
  335. calcnormals(obj[v]^.face^,obj[v]^.vert^,obj[v]^.faces);
  336. end;
  337. savedcc(paramstr(2){'ufo3d.dcc'},1,objcnt);
  338. writeln(objcnt);
  339. end.
  340.